上一章讲述了组件的本质,知道了一个组件的产出是 VNode,渲染器(Renderer)的渲染目标也是 VNode。可见 VNode 在框架设计的整个环节中都非常重要,甚至设计 VNode 本身就是在设计框架,VNode 的设计还会对后续算法的性能产生影响。本章我们就着手对 VNode 进行一定的设计,尝试用 VNode 描述各类渲染内容。
# 用 VNode 描述真实 DOM
一个 html 标签有它的名字、属性、事件、样式、子节点等诸多信息,这些内容都需要在 VNode 中体现,我们可以用如下对象来描述一个红色背景的正方形 div 元素:
const elementVNode = {
tag: 'div',
data: {
style: {
width: '100px',
height: '100px',
backgroundColor: 'red'
}
}
}
@前端进阶之旅: 代码已经复制到剪贴板
我们使用 tag 属性来存储标签的名字,用 data 属性来存储该标签的附加信息,比如 style、class、事件等,通常我们把一个 VNode 对象的 data 属性称为 VNodeData。
为了描述子节点,我们需要给 VNode 对象添加 children 属性,如下 VNode 对象用来描述一个有子节点的 div 元素:
const elementVNode = {
tag: 'div',
data: null,
children: {
tag: 'span',
data: null
}
}
@前端进阶之旅: 代码已经复制到剪贴板
若有多个子节点,则可以把 children 属性设计为一个数组:
const elementVNode = {
tag: 'div',
data: null,
children: [
{
tag: 'h1',
data: null
},
{
tag: 'p',
data: null
}
]
}
@前端进阶之旅: 代码已经复制到剪贴板
除了标签元素之外,DOM 中还有文本节点,我们可以用如下 VNode 对象来描述一个文本节点:
